In [3]:
import pandas as pd
import numpy as np
import datetime as dt
In [4]:
stock_df = pd.read_csv('Amazon.csv')
stock_df.head()
Out[4]:
| Date | Open | High | Low | Close | Volume | Adj Close | |
|---|---|---|---|---|---|---|---|
| 0 | 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 |
| 1 | 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 |
| 2 | 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 |
| 3 | 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 |
| 4 | 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 |
In [5]:
stock_df.isnull().sum()
Out[5]:
Date 0 Open 0 High 0 Low 0 Close 0 Volume 0 Adj Close 0 dtype: int64
In [6]:
stock_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1250 entries, 0 to 1249 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Date 1250 non-null object 1 Open 1250 non-null float64 2 High 1250 non-null float64 3 Low 1250 non-null float64 4 Close 1250 non-null float64 5 Volume 1250 non-null int64 6 Adj Close 1250 non-null float64 dtypes: float64(5), int64(1), object(1) memory usage: 68.5+ KB
In [7]:
stock_df['Daily Return'] = stock_df['Adj Close'].pct_change(1)*100
In [8]:
stock_df.head(10)
Out[8]:
| Date | Open | High | Low | Close | Volume | Adj Close | Daily Return | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 | NaN |
| 1 | 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 | 1.277531 |
| 2 | 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 | 0.447601 |
| 3 | 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 | 1.616252 |
| 4 | 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 | 1.442468 |
| 5 | 1/9/2018 | 62.845001 | 62.966499 | 62.088001 | 62.634998 | 73226000 | 62.634998 | 0.467571 |
| 6 | 1/10/2018 | 62.257500 | 62.716499 | 61.861500 | 62.716499 | 53720000 | 62.716499 | 0.130121 |
| 7 | 1/11/2018 | 62.987000 | 63.838501 | 62.823002 | 63.834000 | 62500000 | 63.834000 | 1.781828 |
| 8 | 1/12/2018 | 63.669498 | 65.288002 | 63.669498 | 65.260002 | 108874000 | 65.260002 | 2.233923 |
| 9 | 1/16/2018 | 66.150002 | 66.997002 | 64.614998 | 65.242996 | 144414000 | 65.242996 | -0.026059 |
In [9]:
stock_df['Daily Return'].replace(np.nan,0,inplace=True)
stock_df
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\1069298868.py:1: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.
The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.
For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.
stock_df['Daily Return'].replace(np.nan,0,inplace=True)
Out[9]:
| Date | Open | High | Low | Close | Volume | Adj Close | Daily Return | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 | 0.000000 |
| 1 | 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 | 1.277531 |
| 2 | 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 | 0.447601 |
| 3 | 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 | 1.616252 |
| 4 | 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 | 1.442468 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1245 | 12/12/2022 | 89.209999 | 90.580002 | 87.870003 | 90.550003 | 61999800 | 90.550003 | 1.638800 |
| 1246 | 12/13/2022 | 95.230003 | 96.250000 | 90.519997 | 92.489998 | 100212000 | 92.489998 | 2.142457 |
| 1247 | 12/14/2022 | 92.500000 | 93.459999 | 89.870003 | 91.580002 | 70298000 | 91.580002 | -0.983886 |
| 1248 | 12/15/2022 | 89.889999 | 89.970001 | 87.470001 | 88.449997 | 84802900 | 88.449997 | -3.417782 |
| 1249 | 12/16/2022 | 88.269997 | 89.349998 | 86.730003 | 87.860001 | 146044000 | 87.860001 | -0.667039 |
1250 rows × 8 columns
In [10]:
stock_df.describe().round(2)
Out[10]:
| Open | High | Low | Close | Volume | Adj Close | Daily Return | |
|---|---|---|---|---|---|---|---|
| count | 1250.00 | 1250.00 | 1250.00 | 1250.00 | 1.250000e+03 | 1250.00 | 1250.00 |
| mean | 120.15 | 121.59 | 118.54 | 120.07 | 8.670803e+07 | 120.07 | 0.06 |
| std | 35.66 | 36.04 | 35.23 | 35.59 | 4.077817e+07 | 35.59 | 2.25 |
| min | 58.60 | 59.50 | 58.53 | 59.45 | 1.762600e+07 | 59.45 | -14.05 |
| 25% | 89.21 | 89.90 | 88.10 | 89.13 | 5.897078e+07 | 89.13 | -1.04 |
| 50% | 108.29 | 111.70 | 106.86 | 108.73 | 7.515300e+07 | 108.73 | 0.12 |
| 75% | 158.39 | 160.05 | 156.28 | 158.11 | 1.027046e+08 | 158.11 | 1.17 |
| max | 187.20 | 188.65 | 184.84 | 186.57 | 3.113460e+08 | 186.57 | 13.54 |
In [11]:
import plotly.express as px
In [12]:
fig = px.line(title="Amazon.com INC (AMZN) adjusted closing price[$]")
fig.add_scatter(x=stock_df['Date'], y=stock_df['Adj Close'], name= 'Adj close')
In [13]:
def financial_plot(df, title):
fig = px.line(title=title)
for i in df.columns[1:]:
fig.add_scatter(x=df['Date'], y=df[i], name= i)
fig.update_traces(line_width= 3)
fig.update_layout({'plot_bgcolor' : "white"})
df['Date'] = pd.to_datetime(df['Date'])
fig.update_xaxes(tickformat="%d-%b-%Y")
fig.show()
In [14]:
financial_plot(stock_df.drop(['Volume','Daily Return'], axis=1), "Amazon.com INC (AMZN) Stock price[$]")
In [15]:
financial_plot(stock_df.iloc[:,[0,5]], "Amazon.com INC (AMZN) Trading volume")
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\530847936.py:9: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
In [16]:
financial_plot(stock_df.iloc[:,[0,7]], "Amazon.com INC (AMZN) Daily return")
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\530847936.py:9: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
In [17]:
def percentage_return_classifier(percentage_return):
if percentage_return > -0.3 and percentage_return <= 0.3:
return 'Insignificant change'
elif percentage_return > 0.3 and percentage_return <= 3:
return 'Positive change'
elif percentage_return > -3 and percentage_return <= -0.3:
return 'Negative change'
elif percentage_return > 3 and percentage_return <= 7:
return 'Large positive change'
elif percentage_return > -7 and percentage_return <= -3:
return 'Large negative change'
elif percentage_return > 7:
return 'Bull run'
elif percentage_return <= -7:
return 'Bear sell off'
In [18]:
stock_df['Trend'] = stock_df['Daily Return'].apply(percentage_return_classifier)
stock_df
Out[18]:
| Date | Open | High | Low | Close | Volume | Adj Close | Daily Return | Trend | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 | 0.000000 | Insignificant change |
| 1 | 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 | 1.277531 | Positive change |
| 2 | 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 | 0.447601 | Positive change |
| 3 | 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 | 1.616252 | Positive change |
| 4 | 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 | 1.442468 | Positive change |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1245 | 12/12/2022 | 89.209999 | 90.580002 | 87.870003 | 90.550003 | 61999800 | 90.550003 | 1.638800 | Positive change |
| 1246 | 12/13/2022 | 95.230003 | 96.250000 | 90.519997 | 92.489998 | 100212000 | 92.489998 | 2.142457 | Positive change |
| 1247 | 12/14/2022 | 92.500000 | 93.459999 | 89.870003 | 91.580002 | 70298000 | 91.580002 | -0.983886 | Negative change |
| 1248 | 12/15/2022 | 89.889999 | 89.970001 | 87.470001 | 88.449997 | 84802900 | 88.449997 | -3.417782 | Large negative change |
| 1249 | 12/16/2022 | 88.269997 | 89.349998 | 86.730003 | 87.860001 | 146044000 | 87.860001 | -0.667039 | Negative change |
1250 rows × 9 columns
In [19]:
trend_summary = stock_df['Trend'].value_counts()
trend_summary
Out[19]:
Trend Positive change 470 Negative change 405 Insignificant change 190 Large positive change 86 Large negative change 82 Bear sell off 9 Bull run 8 Name: count, dtype: int64
In [20]:
import matplotlib.pyplot as plt
plt.figure(figsize=(7,8))
trend_summary.plot(kind='pie', y='trend')
Out[20]:
<Axes: ylabel='count'>
In [22]:
import cufflinks as cf
cf.go_offline()
In [23]:
stock_df
Out[23]:
| Date | Open | High | Low | Close | Volume | Adj Close | Daily Return | Trend | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 | 0.000000 | Insignificant change |
| 1 | 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 | 1.277531 | Positive change |
| 2 | 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 | 0.447601 | Positive change |
| 3 | 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 | 1.616252 | Positive change |
| 4 | 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 | 1.442468 | Positive change |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1245 | 12/12/2022 | 89.209999 | 90.580002 | 87.870003 | 90.550003 | 61999800 | 90.550003 | 1.638800 | Positive change |
| 1246 | 12/13/2022 | 95.230003 | 96.250000 | 90.519997 | 92.489998 | 100212000 | 92.489998 | 2.142457 | Positive change |
| 1247 | 12/14/2022 | 92.500000 | 93.459999 | 89.870003 | 91.580002 | 70298000 | 91.580002 | -0.983886 | Negative change |
| 1248 | 12/15/2022 | 89.889999 | 89.970001 | 87.470001 | 88.449997 | 84802900 | 88.449997 | -3.417782 | Large negative change |
| 1249 | 12/16/2022 | 88.269997 | 89.349998 | 86.730003 | 87.860001 | 146044000 | 87.860001 | -0.667039 | Negative change |
1250 rows × 9 columns
In [24]:
stock_df.set_index('Date', inplace=True)
stock_df
Out[24]:
| Open | High | Low | Close | Volume | Adj Close | Daily Return | Trend | |
|---|---|---|---|---|---|---|---|---|
| Date | ||||||||
| 1/2/2018 | 58.599998 | 59.500000 | 58.525501 | 59.450500 | 53890000 | 59.450500 | 0.000000 | Insignificant change |
| 1/3/2018 | 59.415001 | 60.274502 | 59.415001 | 60.209999 | 62176000 | 60.209999 | 1.277531 | Positive change |
| 1/4/2018 | 60.250000 | 60.793499 | 60.233002 | 60.479500 | 60442000 | 60.479500 | 0.447601 | Positive change |
| 1/5/2018 | 60.875500 | 61.457001 | 60.500000 | 61.457001 | 70894000 | 61.457001 | 1.616252 | Positive change |
| 1/8/2018 | 61.799999 | 62.653999 | 61.601501 | 62.343498 | 85590000 | 62.343498 | 1.442468 | Positive change |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 12/12/2022 | 89.209999 | 90.580002 | 87.870003 | 90.550003 | 61999800 | 90.550003 | 1.638800 | Positive change |
| 12/13/2022 | 95.230003 | 96.250000 | 90.519997 | 92.489998 | 100212000 | 92.489998 | 2.142457 | Positive change |
| 12/14/2022 | 92.500000 | 93.459999 | 89.870003 | 91.580002 | 70298000 | 91.580002 | -0.983886 | Negative change |
| 12/15/2022 | 89.889999 | 89.970001 | 87.470001 | 88.449997 | 84802900 | 88.449997 | -3.417782 | Large negative change |
| 12/16/2022 | 88.269997 | 89.349998 | 86.730003 | 87.860001 | 146044000 | 87.860001 | -0.667039 | Negative change |
1250 rows × 8 columns
In [25]:
figure = cf.QuantFig(stock_df, title='Amazon.com INC (AMZN) Candlestick chart', name = 'AMZN')
figure.add_rsi(periods=14, color='java')
figure.add_bollinger_bands(periods=20, boll_std=2, colors=['magenta', 'grey'], fill=True)
#figure.add_sma(periods=[14,21], column= 'Close', colors=['magenta', 'grey'])
figure.add_sma(periods=[14, 21], column='Close', colors=['magenta', 'grey'])
#figure.add_volume()
figure.iplot(theme="white", up_color="green", down_color="red")
#figure.iplot(theme="white", up_color="green", down_color="red")
#figure.iplot(as_candlestick=True, theme="white", up_color="green", down_color="red")
In [26]:
close_prices_df = pd.read_csv("stock_prices.csv")
close_prices_df
Out[26]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2014 | 19.898500 | 69.512543 | 75.620926 | 14.121004 | 27.855856 | 71.443314 | 45.640057 | 54.709999 | 20.879053 | 61.941517 |
| 1 | 1/3/2014 | 19.822001 | 69.473892 | 75.956062 | 13.835152 | 27.652653 | 72.086861 | 45.992889 | 54.560001 | 20.920183 | 61.872295 |
| 2 | 1/6/2014 | 19.681499 | 68.561180 | 75.327690 | 13.923512 | 27.960960 | 72.463608 | 46.259468 | 57.200001 | 20.940746 | 62.018425 |
| 3 | 1/7/2014 | 19.901501 | 68.785461 | 75.662811 | 13.996271 | 28.500000 | 74.001869 | 45.726311 | 57.919998 | 21.070980 | 62.618301 |
| 4 | 1/8/2014 | 20.096001 | 68.947906 | 74.850121 | 13.965082 | 28.559309 | 73.899841 | 46.157543 | 58.230000 | 21.214928 | 61.710812 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 12/12/2022 | 90.550003 | 233.059998 | 437.049988 | 42.500000 | 93.309998 | 177.839996 | 134.210007 | 114.709999 | 52.160000 | 152.470001 |
| 2253 | 12/13/2022 | 92.489998 | 235.490005 | 437.190002 | 42.540001 | 95.629997 | 179.210007 | 134.080002 | 120.150002 | 53.070000 | 152.240005 |
| 2254 | 12/14/2022 | 91.580002 | 234.479996 | 438.440002 | 42.820000 | 95.070000 | 179.759995 | 133.410004 | 121.589996 | 54.480000 | 152.839996 |
| 2255 | 12/15/2022 | 88.449997 | 230.660004 | 429.790008 | 42.380001 | 90.860001 | 177.490005 | 130.100006 | 116.150002 | 53.610001 | 151.110001 |
| 2256 | 12/16/2022 | 87.860001 | 232.720001 | 431.089996 | 41.930000 | 90.260002 | 175.669998 | 129.289993 | 119.430000 | 51.400002 | 150.440002 |
2257 rows × 11 columns
In [27]:
daily_returns_df = close_prices_df.iloc[:,1:].pct_change()*100
daily_returns_df.replace(np.nan, 0, inplace = True)
daily_returns_df
Out[27]:
| AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 1 | -0.384451 | -0.055602 | 0.443179 | -2.024307 | -0.729481 | 0.900780 | 0.773077 | -0.274169 | 0.196992 | -0.111753 |
| 2 | -0.708814 | -1.313748 | -0.827284 | 0.638662 | 1.114930 | 0.522629 | 0.579608 | 4.838708 | 0.098293 | 0.236179 |
| 3 | 1.117807 | 0.327126 | 0.444884 | 0.522567 | 1.927829 | 2.122805 | -1.152537 | 1.258737 | 0.621916 | 0.967255 |
| 4 | 0.977313 | 0.236162 | -1.074095 | -0.222838 | 0.208102 | -0.137872 | 0.943073 | 0.535223 | 0.683156 | -1.449240 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 1.638800 | 2.538609 | 0.515165 | 2.607441 | 0.517070 | 1.194942 | 1.551152 | -1.026749 | 0.850732 | 1.027036 |
| 2253 | 2.142457 | 1.042653 | 0.032036 | 0.094120 | 2.486336 | 0.770361 | -0.096867 | 4.742396 | 1.744632 | -0.150847 |
| 2254 | -0.983886 | -0.428897 | 0.285917 | 0.658201 | -0.585588 | 0.306896 | -0.499700 | 1.198498 | 2.656868 | 0.394108 |
| 2255 | -3.417782 | -1.629133 | -1.972903 | -1.027554 | -4.428315 | -1.262789 | -2.481072 | -4.474048 | -1.596914 | -1.131900 |
| 2256 | -0.667039 | 0.893088 | 0.302470 | -1.061823 | -0.660355 | -1.025414 | -0.622608 | 2.823933 | -4.122363 | -0.443384 |
2257 rows × 10 columns
In [28]:
daily_returns_df.insert(0, "Date", close_prices_df['Date'])
In [29]:
daily_returns_df
Out[29]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1/2/2014 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 1 | 1/3/2014 | -0.384451 | -0.055602 | 0.443179 | -2.024307 | -0.729481 | 0.900780 | 0.773077 | -0.274169 | 0.196992 | -0.111753 |
| 2 | 1/6/2014 | -0.708814 | -1.313748 | -0.827284 | 0.638662 | 1.114930 | 0.522629 | 0.579608 | 4.838708 | 0.098293 | 0.236179 |
| 3 | 1/7/2014 | 1.117807 | 0.327126 | 0.444884 | 0.522567 | 1.927829 | 2.122805 | -1.152537 | 1.258737 | 0.621916 | 0.967255 |
| 4 | 1/8/2014 | 0.977313 | 0.236162 | -1.074095 | -0.222838 | 0.208102 | -0.137872 | 0.943073 | 0.535223 | 0.683156 | -1.449240 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 12/12/2022 | 1.638800 | 2.538609 | 0.515165 | 2.607441 | 0.517070 | 1.194942 | 1.551152 | -1.026749 | 0.850732 | 1.027036 |
| 2253 | 12/13/2022 | 2.142457 | 1.042653 | 0.032036 | 0.094120 | 2.486336 | 0.770361 | -0.096867 | 4.742396 | 1.744632 | -0.150847 |
| 2254 | 12/14/2022 | -0.983886 | -0.428897 | 0.285917 | 0.658201 | -0.585588 | 0.306896 | -0.499700 | 1.198498 | 2.656868 | 0.394108 |
| 2255 | 12/15/2022 | -3.417782 | -1.629133 | -1.972903 | -1.027554 | -4.428315 | -1.262789 | -2.481072 | -4.474048 | -1.596914 | -1.131900 |
| 2256 | 12/16/2022 | -0.667039 | 0.893088 | 0.302470 | -1.061823 | -0.660355 | -1.025414 | -0.622608 | 2.823933 | -4.122363 | -0.443384 |
2257 rows × 11 columns
In [30]:
financial_plot(close_prices_df,"Adjusted closing price [$]")
In [31]:
financial_plot(daily_returns_df,"Percentage daily returns [$]")
In [32]:
fig = px.histogram(daily_returns_df.drop(columns = ["Date"]))
fig.update_layout({'plot_bgcolor': "white"})
In [33]:
import seaborn as sns
In [34]:
plt.figure(figsize=[10,6])
sns.heatmap(daily_returns_df.drop(columns=["Date"]).corr(),annot= True, cmap="crest");
In [35]:
sns.pairplot(daily_returns_df);
In [36]:
# want to set all the prices to start at value 1 so that I can see my investments over time
def price_scaling(raw_prices_df):
scaled_prices_df = raw_prices_df.copy()
for i in raw_prices_df.columns[1:]:
scaled_prices_df[i] = raw_prices_df[i]/raw_prices_df[i][0]
return scaled_prices_df
In [37]:
price_scaling(close_prices_df)
Out[37]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014-01-02 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
| 1 | 2014-01-03 | 0.996155 | 0.999444 | 1.004432 | 0.979757 | 0.992705 | 1.009008 | 1.007731 | 0.997258 | 1.001970 | 0.998882 |
| 2 | 2014-01-06 | 0.989095 | 0.986314 | 0.996122 | 0.986014 | 1.003773 | 1.014281 | 1.013572 | 1.045513 | 1.002955 | 1.001242 |
| 3 | 2014-01-07 | 1.000151 | 0.989540 | 1.000554 | 0.991167 | 1.023124 | 1.035812 | 1.001890 | 1.058673 | 1.009192 | 1.010926 |
| 4 | 2014-01-08 | 1.009925 | 0.991877 | 0.989807 | 0.988958 | 1.025253 | 1.034384 | 1.011338 | 1.064339 | 1.016087 | 0.996275 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 2022-12-12 | 4.550594 | 3.352776 | 5.779485 | 3.009701 | 3.349744 | 2.489246 | 2.940619 | 2.096692 | 2.498198 | 2.461515 |
| 2253 | 2022-12-13 | 4.648089 | 3.387734 | 5.781336 | 3.012534 | 3.433030 | 2.508422 | 2.937770 | 2.196125 | 2.541782 | 2.457802 |
| 2254 | 2022-12-14 | 4.602357 | 3.373204 | 5.797866 | 3.032362 | 3.412927 | 2.516121 | 2.923090 | 2.222446 | 2.609314 | 2.467489 |
| 2255 | 2022-12-15 | 4.445058 | 3.318250 | 5.683480 | 3.001203 | 3.261792 | 2.484347 | 2.850566 | 2.123012 | 2.567645 | 2.439559 |
| 2256 | 2022-12-16 | 4.415408 | 3.347885 | 5.700671 | 2.969336 | 3.240252 | 2.458872 | 2.832818 | 2.182965 | 2.461798 | 2.428743 |
2257 rows × 11 columns
In [38]:
financial_plot(price_scaling(close_prices_df), "Scaled prices")
Random weight generation¶
In [40]:
import random
def portfolio_weight_generation(n):
weights = []
for i in range(n):
weights.append(random.random())
weights = weights/np.sum(weights)
return weights
In [41]:
weights = portfolio_weight_generation(10)
print(weights)
[0.07307595 0.03976802 0.12957574 0.09008053 0.09570124 0.10181999 0.19088182 0.15828769 0.06655204 0.05425697]
Asset allocation¶
Assumptions:
Assuming initial $1MN investmesnts across 10 above stocks with randomly generated weights.
Assuming random weights, if specific weights are given then insert that only.
In [43]:
portfolio_df = close_prices_df.copy()
scaled_df = price_scaling(portfolio_df)
scaled_df
Out[43]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014-01-02 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
| 1 | 2014-01-03 | 0.996155 | 0.999444 | 1.004432 | 0.979757 | 0.992705 | 1.009008 | 1.007731 | 0.997258 | 1.001970 | 0.998882 |
| 2 | 2014-01-06 | 0.989095 | 0.986314 | 0.996122 | 0.986014 | 1.003773 | 1.014281 | 1.013572 | 1.045513 | 1.002955 | 1.001242 |
| 3 | 2014-01-07 | 1.000151 | 0.989540 | 1.000554 | 0.991167 | 1.023124 | 1.035812 | 1.001890 | 1.058673 | 1.009192 | 1.010926 |
| 4 | 2014-01-08 | 1.009925 | 0.991877 | 0.989807 | 0.988958 | 1.025253 | 1.034384 | 1.011338 | 1.064339 | 1.016087 | 0.996275 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 2022-12-12 | 4.550594 | 3.352776 | 5.779485 | 3.009701 | 3.349744 | 2.489246 | 2.940619 | 2.096692 | 2.498198 | 2.461515 |
| 2253 | 2022-12-13 | 4.648089 | 3.387734 | 5.781336 | 3.012534 | 3.433030 | 2.508422 | 2.937770 | 2.196125 | 2.541782 | 2.457802 |
| 2254 | 2022-12-14 | 4.602357 | 3.373204 | 5.797866 | 3.032362 | 3.412927 | 2.516121 | 2.923090 | 2.222446 | 2.609314 | 2.467489 |
| 2255 | 2022-12-15 | 4.445058 | 3.318250 | 5.683480 | 3.001203 | 3.261792 | 2.484347 | 2.850566 | 2.123012 | 2.567645 | 2.439559 |
| 2256 | 2022-12-16 | 4.415408 | 3.347885 | 5.700671 | 2.969336 | 3.240252 | 2.458872 | 2.832818 | 2.182965 | 2.461798 | 2.428743 |
2257 rows × 11 columns
In [44]:
initial_investment = 1000000
for i, stock in enumerate(scaled_df.columns[1:]):
portfolio_df[stock] = weights[i] * scaled_df[stock] * initial_investment
portfolio_df.round(1)
Out[44]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014-01-02 | 73075.9 | 39768.0 | 129575.7 | 90080.5 | 95701.2 | 101820.0 | 190881.8 | 158287.7 | 66552.0 | 54257.0 |
| 1 | 2014-01-03 | 72795.0 | 39745.9 | 130150.0 | 88257.0 | 95003.1 | 102737.2 | 192357.5 | 157853.7 | 66683.1 | 54196.3 |
| 2 | 2014-01-06 | 72279.0 | 39223.7 | 129073.3 | 88820.7 | 96062.3 | 103274.1 | 193472.4 | 165491.8 | 66748.7 | 54324.3 |
| 3 | 2014-01-07 | 73087.0 | 39352.1 | 129647.5 | 89284.8 | 97914.3 | 105466.4 | 191242.6 | 167574.9 | 67163.8 | 54849.8 |
| 4 | 2014-01-08 | 73801.3 | 39445.0 | 128255.0 | 89085.9 | 98118.0 | 105321.0 | 193046.1 | 168471.8 | 67622.6 | 54054.9 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 2022-12-12 | 332539.0 | 133333.3 | 748881.0 | 271115.5 | 320574.7 | 253455.0 | 561310.7 | 331880.5 | 166260.1 | 133554.4 |
| 2253 | 2022-12-13 | 339663.5 | 134723.5 | 749120.9 | 271370.6 | 328545.3 | 255407.5 | 560766.9 | 347619.6 | 169160.8 | 133352.9 |
| 2254 | 2022-12-14 | 336321.6 | 134145.7 | 751262.8 | 273156.8 | 326621.3 | 256191.4 | 557964.8 | 351785.8 | 173655.1 | 133878.5 |
| 2255 | 2022-12-15 | 324826.9 | 131960.2 | 736441.1 | 270350.0 | 312157.5 | 252956.2 | 544121.3 | 336046.7 | 170882.0 | 132363.1 |
| 2256 | 2022-12-16 | 322660.1 | 133138.8 | 738668.6 | 267479.3 | 310096.2 | 250362.4 | 540733.5 | 345536.5 | 163837.6 | 131776.2 |
2257 rows × 11 columns
In [45]:
def asset_allocation(df, weights,initial_investment):
portfolio_df = df.copy()
scaled_df = price_scaling(df)
for i, stock in enumerate(scaled_df.columns[1:]):
portfolio_df[stock] = weights[i] * scaled_df[stock] * initial_investment
portfolio_df["Portfolio Value [$]"]=portfolio_df[portfolio_df!='Date'].sum(axis=1, numeric_only=True)
portfolio_df["Portfolio daily return [$]"] = portfolio_df['Portfolio Value [$]'].pct_change()*100
portfolio_df.replace(np.nan, 0, inplace=True)
return portfolio_df
In [46]:
portfolio_df = asset_allocation(close_prices_df, weights, 1000000)
portfolio_df.round(2)
Out[46]:
| Date | AMZN | CAT | DE | EXC | GOOGL | JNJ | JPM | META | PFE | PG | Portfolio Value [$] | Portfolio daily return [$] | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014-01-02 | 73075.95 | 39768.02 | 129575.74 | 90080.53 | 95701.24 | 101819.99 | 190881.82 | 158287.69 | 66552.04 | 54256.97 | 1000000.00 | 0.00 |
| 1 | 2014-01-03 | 72795.01 | 39745.91 | 130150.00 | 88257.02 | 95003.12 | 102737.17 | 192357.48 | 157853.72 | 66683.14 | 54196.34 | 999778.90 | -0.02 |
| 2 | 2014-01-06 | 72279.03 | 39223.75 | 129073.29 | 88820.69 | 96062.34 | 103274.10 | 193472.41 | 165491.80 | 66748.68 | 54324.34 | 1008770.41 | 0.90 |
| 3 | 2014-01-07 | 73086.97 | 39352.06 | 129647.51 | 89284.84 | 97914.26 | 105466.41 | 191242.56 | 167574.90 | 67163.80 | 54849.79 | 1015583.11 | 0.68 |
| 4 | 2014-01-08 | 73801.25 | 39445.00 | 128254.98 | 89085.88 | 98118.02 | 105321.00 | 193046.12 | 168471.80 | 67622.64 | 54054.89 | 1017221.57 | 0.16 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2252 | 2022-12-12 | 332538.99 | 133333.28 | 748881.03 | 271115.46 | 320574.71 | 253455.02 | 561310.67 | 331880.49 | 166260.13 | 133554.37 | 3252904.15 | 0.99 |
| 2253 | 2022-12-13 | 339663.50 | 134723.48 | 749120.94 | 271370.64 | 328545.27 | 255407.54 | 560766.94 | 347619.57 | 169160.76 | 133352.91 | 3289731.56 | 1.13 |
| 2254 | 2022-12-14 | 336321.60 | 134145.66 | 751262.81 | 273156.80 | 326621.35 | 256191.38 | 557964.79 | 351785.78 | 173655.14 | 133878.46 | 3294983.77 | 0.16 |
| 2255 | 2022-12-15 | 324826.86 | 131960.25 | 736441.12 | 270349.97 | 312157.53 | 252956.22 | 544121.28 | 336046.72 | 170882.02 | 132363.09 | 3212105.06 | -2.52 |
| 2256 | 2022-12-16 | 322660.14 | 133138.77 | 738668.64 | 267479.33 | 310096.18 | 250362.37 | 540733.54 | 345536.46 | 163837.64 | 131776.22 | 3204289.28 | -0.24 |
2257 rows × 13 columns
In [47]:
financial_plot(portfolio_df[["Date","Portfolio daily return [$]"]], "Portfolio percentage daily return")
In [48]:
financial_plot(portfolio_df[["Date","Portfolio Value [$]"]], "Portfolio actual value return")
In [49]:
financial_plot(portfolio_df.drop(columns=['Portfolio Value [$]','Portfolio daily return [$]']),"Each stock return")
In [192]:
def simulation_engine(weights, initial_investment):
portfolio_df = asset_allocation(close_prices_df, weights, initial_investment)
return_on_investment = ((portfolio_df['Portfolio Value [$]'][-1:] -
portfolio_df['Portfolio Value [$]'][0])/
portfolio_df['Portfolio Value [$]'][0]) * 100
portfolio_daily_return_df = portfolio_df.drop(columns = ['Date', 'Portfolio Value [$]', 'Portfolio daily return [$]'])
portfolio_daily_return_df = portfolio_daily_return_df.pct_change(1)
expected_portfolio_return = np.sum(weights * portfolio_daily_return_df.mean() ) * 252
covariance = portfolio_daily_return_df.cov() * 252
expected_volatility = np.sqrt(np.dot(weights.T, np.dot(covariance, weights)))
rf = 0.035 #risk free rate at the end of 2022
sharpe_ratio = (expected_portfolio_return - rf)/expected_volatility
return expected_portfolio_return, expected_volatility, sharpe_ratio, portfolio_df['Portfolio Value [$]'][-1:].values[0], return_on_investment.values[0]
In [194]:
initial_investment = 1000000
portfolio_metrics = simulation_engine(weights, initial_investment)
In [196]:
print('Expected Portfolio Annual Return = {:.2f}%'.format(portfolio_metrics[0] * 100))
print('Portfolio Standard Deviation (Volatility) = {:.2f}%'.format(portfolio_metrics[1] * 100))
print('Sharpe Ratio = {:.2f}'.format(portfolio_metrics[2]))
print('Portfolio Final Value = ${:.2f}'.format(portfolio_metrics[3]))
print('Return on Investment = {:.2f}%'.format(portfolio_metrics[4]))
Expected Portfolio Annual Return = 16.04% Portfolio Standard Deviation (Volatility) = 17.01% Sharpe Ratio = 0.74 Portfolio Final Value = $3213742.52 Return on Investment = 221.37%
Monte Carlo Simulations¶
In [199]:
sim_runs = 100
#n = weight_runs.shape[1]
n=10
initial_investment = 1000000
weight_runs = np.zeros((sim_runs,n))
sharpe_ratio_runs = np.zeros(sim_runs)
expected_portfolio_return_runs = np.zeros(sim_runs)
volatility_runs = np.zeros(sim_runs)
return_on_investment_runs = np.zeros(sim_runs)
final_values_runs = np.zeros(sim_runs)
for i in range(sim_runs):
weights = portfolio_weight_generation(n)
weight_runs[i,:] = weights
expected_portfolio_return_runs[i], volatility_runs[i], sharpe_ratio_runs[i], final_values_runs[i], return_on_investment_runs[i] = simulation_engine(weights, initial_investment)
print("Simulation Run = {}".format(i))
print("Weights = {}, Final Value = ${:.2f}, Sharpe Ratio = {:.2f}".format(weight_runs[i].round(3), final_values_runs[i], sharpe_ratio_runs[i]))
print('\n')
Simulation Run = 0 Weights = [0.09 0.066 0.113 0.006 0.003 0.184 0.123 0.141 0.174 0.103], Final Value = $3069452.18, Sharpe Ratio = 0.69 Simulation Run = 1 Weights = [0.165 0.05 0.048 0.047 0.178 0.106 0.06 0.112 0.12 0.115], Final Value = $3131939.33, Sharpe Ratio = 0.68 Simulation Run = 2 Weights = [0.166 0.189 0.132 0.028 0.048 0.048 0.13 0.006 0.136 0.117], Final Value = $3476586.59, Sharpe Ratio = 0.73 Simulation Run = 3 Weights = [0.039 0.18 0.039 0.004 0.056 0.15 0.191 0.128 0.077 0.135], Final Value = $2898777.25, Sharpe Ratio = 0.64 Simulation Run = 4 Weights = [0.026 0.168 0.13 0.074 0.128 0.135 0.052 0.125 0.052 0.111], Final Value = $3200060.54, Sharpe Ratio = 0.69 Simulation Run = 5 Weights = [0.136 0.146 0.015 0.158 0.162 0.016 0.128 0.129 0.004 0.108], Final Value = $3118306.91, Sharpe Ratio = 0.66 Simulation Run = 6 Weights = [0.125 0.085 0.189 0.04 0.075 0.096 0.053 0.096 0.093 0.148], Final Value = $3459062.25, Sharpe Ratio = 0.74 Simulation Run = 7 Weights = [0.017 0.051 0.086 0.002 0.017 0.1 0.173 0.185 0.185 0.184], Final Value = $2839560.03, Sharpe Ratio = 0.64 Simulation Run = 8 Weights = [0.031 0.155 0.181 0.007 0.141 0.024 0.067 0.159 0.092 0.143], Final Value = $3334941.37, Sharpe Ratio = 0.69 Simulation Run = 9 Weights = [0.104 0.026 0.112 0.109 0.097 0.153 0.113 0.168 0.023 0.095], Final Value = $3172094.96, Sharpe Ratio = 0.69 Simulation Run = 10 Weights = [0.205 0.024 0.046 0.22 0. 0.144 0.027 0.061 0.05 0.223], Final Value = $3128432.34, Sharpe Ratio = 0.72 Simulation Run = 11 Weights = [0.18 0.079 0.016 0.17 0.081 0.11 0.076 0.047 0.176 0.066], Final Value = $3095819.14, Sharpe Ratio = 0.71 Simulation Run = 12 Weights = [0.074 0.214 0.013 0.149 0.174 0.16 0.017 0.069 0.013 0.117], Final Value = $3031902.87, Sharpe Ratio = 0.68 Simulation Run = 13 Weights = [0.196 0.148 0.077 0.001 0.1 0.129 0.19 0.049 0.06 0.05 ], Final Value = $3358006.16, Sharpe Ratio = 0.70 Simulation Run = 14 Weights = [0.015 0.118 0.027 0.111 0.008 0.081 0.23 0.107 0.122 0.18 ], Final Value = $2796263.07, Sharpe Ratio = 0.63 Simulation Run = 15 Weights = [0.015 0.011 0.123 0.039 0.043 0.214 0.118 0.083 0.272 0.082], Final Value = $2969788.26, Sharpe Ratio = 0.67 Simulation Run = 16 Weights = [0.007 0.135 0.003 0.185 0.087 0.127 0.118 0.198 0.032 0.11 ], Final Value = $2747933.11, Sharpe Ratio = 0.62 Simulation Run = 17 Weights = [0.126 0.092 0.014 0.13 0.167 0.227 0.007 0.004 0.183 0.05 ], Final Value = $3030200.09, Sharpe Ratio = 0.70 Simulation Run = 18 Weights = [0.076 0.095 0.11 0.07 0.143 0.095 0.112 0.118 0.079 0.101], Final Value = $3204322.33, Sharpe Ratio = 0.70 Simulation Run = 19 Weights = [0.115 0.188 0.13 0.162 0.024 0.003 0.2 0.132 0.042 0.003], Final Value = $3411606.43, Sharpe Ratio = 0.69 Simulation Run = 20 Weights = [0.045 0.055 0.01 0.197 0.017 0.07 0.173 0.116 0.235 0.08 ], Final Value = $2773988.25, Sharpe Ratio = 0.64 Simulation Run = 21 Weights = [0.102 0.119 0.012 0.082 0.159 0.142 0.073 0.112 0.147 0.053], Final Value = $2963780.82, Sharpe Ratio = 0.66 Simulation Run = 22 Weights = [0.03 0.082 0.072 0.107 0.159 0.161 0.069 0.077 0.061 0.183], Final Value = $3001769.61, Sharpe Ratio = 0.69 Simulation Run = 23 Weights = [0.003 0.098 0.118 0.15 0.089 0.128 0.029 0.163 0.159 0.064], Final Value = $3044899.81, Sharpe Ratio = 0.68 Simulation Run = 24 Weights = [0.146 0.032 0.151 0.05 0.156 0.018 0.036 0.153 0.17 0.089], Final Value = $3377941.17, Sharpe Ratio = 0.70 Simulation Run = 25 Weights = [0.126 0.134 0.127 0.083 0.106 0.107 0.111 0.003 0.056 0.147], Final Value = $3396937.76, Sharpe Ratio = 0.74 Simulation Run = 26 Weights = [0.119 0.013 0.173 0.074 0.104 0.062 0.128 0.076 0.11 0.14 ], Final Value = $3407500.41, Sharpe Ratio = 0.74 Simulation Run = 27 Weights = [0.019 0.05 0.143 0.15 0.153 0.136 0.125 0.055 0.053 0.116], Final Value = $3228210.19, Sharpe Ratio = 0.71 Simulation Run = 28 Weights = [0.177 0.174 0.03 0.159 0.053 0.198 0.048 0.082 0.054 0.026], Final Value = $3171924.73, Sharpe Ratio = 0.71 Simulation Run = 29 Weights = [0.099 0.11 0.085 0.136 0.16 0.073 0.006 0.168 0.079 0.084], Final Value = $3173878.74, Sharpe Ratio = 0.68 Simulation Run = 30 Weights = [0.031 0.177 0.096 0.095 0.119 0.14 0.131 0.146 0.043 0.023], Final Value = $3135763.49, Sharpe Ratio = 0.67 Simulation Run = 31 Weights = [0.063 0.17 0.037 0.071 0.152 0.155 0.068 0.014 0.158 0.111], Final Value = $3028670.09, Sharpe Ratio = 0.69 Simulation Run = 32 Weights = [0.098 0.108 0.043 0.112 0.135 0.068 0.096 0.134 0.122 0.083], Final Value = $3047549.96, Sharpe Ratio = 0.67 Simulation Run = 33 Weights = [0.132 0.033 0.071 0.024 0.121 0.089 0.131 0.151 0.103 0.145], Final Value = $3086235.61, Sharpe Ratio = 0.67 Simulation Run = 34 Weights = [0.039 0.231 0.207 0.027 0.05 0.208 0.065 0.01 0.051 0.113], Final Value = $3481623.39, Sharpe Ratio = 0.71 Simulation Run = 35 Weights = [0.049 0.182 0.008 0.122 0.152 0.164 0.042 0.028 0.105 0.147], Final Value = $2927956.06, Sharpe Ratio = 0.68 Simulation Run = 36 Weights = [0.09 0.034 0.212 0.071 0.132 0.069 0.151 0.012 0.024 0.206], Final Value = $3538415.04, Sharpe Ratio = 0.75 Simulation Run = 37 Weights = [0.08 0.176 0.028 0.011 0.189 0.019 0.185 0.19 0.08 0.042], Final Value = $3033477.31, Sharpe Ratio = 0.62 Simulation Run = 38 Weights = [0.007 0.227 0.008 0.012 0.034 0.12 0.142 0.19 0.031 0.227], Final Value = $2728847.92, Sharpe Ratio = 0.61 Simulation Run = 39 Weights = [0.045 0.377 0.013 0.031 0.07 0.109 0.031 0.144 0.121 0.059], Final Value = $2962826.20, Sharpe Ratio = 0.63 Simulation Run = 40 Weights = [0.165 0.002 0.182 0.017 0.192 0.038 0.006 0.001 0.173 0.224], Final Value = $3528546.33, Sharpe Ratio = 0.75 Simulation Run = 41 Weights = [0.142 0.045 0.061 0.038 0.111 0.188 0.001 0.094 0.142 0.177], Final Value = $3050584.99, Sharpe Ratio = 0.70 Simulation Run = 42 Weights = [0.109 0.097 0.1 0.124 0.204 0.02 0.112 0.001 0.118 0.114], Final Value = $3345015.13, Sharpe Ratio = 0.72 Simulation Run = 43 Weights = [0.189 0.099 0.124 0.14 0.033 0.107 0.034 0.113 0.057 0.105], Final Value = $3393101.82, Sharpe Ratio = 0.74 Simulation Run = 44 Weights = [0.086 0.041 0.093 0.093 0.141 0.097 0.144 0.055 0.135 0.115], Final Value = $3158304.11, Sharpe Ratio = 0.71 Simulation Run = 45 Weights = [0.001 0.245 0.012 0.144 0.108 0.084 0.177 0.112 0.074 0.043], Final Value = $2911134.53, Sharpe Ratio = 0.63 Simulation Run = 46 Weights = [0.073 0.035 0.142 0.115 0.052 0.101 0.168 0.126 0.013 0.175], Final Value = $3216965.20, Sharpe Ratio = 0.70 Simulation Run = 47 Weights = [0.075 0.089 0.11 0.143 0.116 0.119 0.107 0.126 0.108 0.008], Final Value = $3209978.72, Sharpe Ratio = 0.70 Simulation Run = 48 Weights = [0.117 0.143 0.086 0.154 0.155 0.151 0.004 0.099 0.004 0.087], Final Value = $3265995.24, Sharpe Ratio = 0.71 Simulation Run = 49 Weights = [0.083 0.079 0.021 0.062 0.031 0.179 0.059 0.133 0.257 0.095], Final Value = $2798726.78, Sharpe Ratio = 0.65 Simulation Run = 50 Weights = [0.129 0.054 0.144 0.183 0.145 0.104 0.094 0.006 0.017 0.125], Final Value = $3462894.69, Sharpe Ratio = 0.75 Simulation Run = 51 Weights = [0.143 0.055 0.144 0.013 0.003 0.189 0.023 0.203 0.19 0.037], Final Value = $3215809.32, Sharpe Ratio = 0.69 Simulation Run = 52 Weights = [0.112 0.196 0.025 0.165 0.08 0.017 0.097 0.16 0.029 0.12 ], Final Value = $3069073.89, Sharpe Ratio = 0.67 Simulation Run = 53 Weights = [0.044 0.099 0.288 0.1 0.042 0.102 0.01 0.216 0.036 0.065], Final Value = $3591901.83, Sharpe Ratio = 0.72 Simulation Run = 54 Weights = [0.059 0.15 0.081 0.157 0.119 0.14 0.112 0.038 0.127 0.016], Final Value = $3173614.55, Sharpe Ratio = 0.70 Simulation Run = 55 Weights = [0.15 0.129 0.179 0.12 0.095 0.029 0.058 0.045 0.061 0.135], Final Value = $3588434.01, Sharpe Ratio = 0.76 Simulation Run = 56 Weights = [0.059 0.181 0.195 0.132 0.092 0.068 0.017 0.029 0.172 0.055], Final Value = $3505530.98, Sharpe Ratio = 0.74 Simulation Run = 57 Weights = [0.048 0.147 0.09 0.056 0.143 0.119 0.111 0.148 0.129 0.01 ], Final Value = $3116248.11, Sharpe Ratio = 0.67 Simulation Run = 58 Weights = [0.139 0.081 0.12 0.044 0.098 0.055 0.163 0.126 0.072 0.101], Final Value = $3313225.79, Sharpe Ratio = 0.70 Simulation Run = 59 Weights = [0.032 0.091 0.057 0.104 0.08 0.078 0.057 0.166 0.169 0.166], Final Value = $2873932.99, Sharpe Ratio = 0.66 Simulation Run = 60 Weights = [0.023 0.039 0.209 0.2 0.177 0.023 0.149 0. 0.047 0.134], Final Value = $3508831.39, Sharpe Ratio = 0.73 Simulation Run = 61 Weights = [0.108 0.06 0.149 0.143 0.059 0.162 0.014 0.154 0.078 0.074], Final Value = $3285998.64, Sharpe Ratio = 0.72 Simulation Run = 62 Weights = [0.103 0.147 0.099 0.028 0.14 0.067 0.122 0.028 0.172 0.093], Final Value = $3270988.53, Sharpe Ratio = 0.71 Simulation Run = 63 Weights = [0.07 0.081 0.051 0.063 0.065 0.08 0.208 0.016 0.229 0.137], Final Value = $2985443.35, Sharpe Ratio = 0.67 Simulation Run = 64 Weights = [0.139 0.123 0.039 0.163 0.164 0.05 0.078 0.016 0.071 0.157], Final Value = $3199000.13, Sharpe Ratio = 0.71 Simulation Run = 65 Weights = [0.072 0.036 0.01 0.148 0.181 0.149 0.095 0.091 0.128 0.089], Final Value = $2889436.61, Sharpe Ratio = 0.66 Simulation Run = 66 Weights = [0.066 0.026 0.091 0.16 0.004 0.012 0.236 0.014 0.179 0.211], Final Value = $3069398.73, Sharpe Ratio = 0.68 Simulation Run = 67 Weights = [0.198 0.111 0.072 0.078 0.198 0.006 0.118 0.172 0.004 0.042], Final Value = $3369232.00, Sharpe Ratio = 0.66 Simulation Run = 68 Weights = [0.007 0.023 0.055 0.2 0.19 0.078 0.018 0.101 0.15 0.178], Final Value = $2897900.19, Sharpe Ratio = 0.66 Simulation Run = 69 Weights = [0.174 0.019 0.033 0.073 0.032 0.11 0.146 0.155 0.12 0.138], Final Value = $2993221.42, Sharpe Ratio = 0.67 Simulation Run = 70 Weights = [0.095 0.163 0.119 0.02 0.044 0.169 0.021 0.133 0.108 0.128], Final Value = $3186952.46, Sharpe Ratio = 0.71 Simulation Run = 71 Weights = [0.098 0.204 0.086 0.021 0.018 0.13 0.094 0.16 0.06 0.129], Final Value = $3124006.20, Sharpe Ratio = 0.68 Simulation Run = 72 Weights = [0.079 0.016 0. 0.186 0.108 0.168 0.116 0.196 0.009 0.121], Final Value = $2794111.85, Sharpe Ratio = 0.62 Simulation Run = 73 Weights = [0.096 0.133 0.026 0.076 0.104 0.09 0.144 0.132 0.077 0.123], Final Value = $2982787.31, Sharpe Ratio = 0.66 Simulation Run = 74 Weights = [0.172 0.027 0.002 0.154 0.237 0.108 0.061 0.055 0.099 0.085], Final Value = $3094417.12, Sharpe Ratio = 0.67 Simulation Run = 75 Weights = [0.083 0.102 0.007 0.146 0.098 0.088 0.145 0.105 0.117 0.108], Final Value = $2910272.22, Sharpe Ratio = 0.67 Simulation Run = 76 Weights = [0.012 0.073 0.114 0.113 0.12 0.141 0.083 0.154 0.109 0.081], Final Value = $3054598.00, Sharpe Ratio = 0.68 Simulation Run = 77 Weights = [0.154 0.035 0.129 0.137 0.047 0.179 0.128 0.062 0.094 0.035], Final Value = $3343923.69, Sharpe Ratio = 0.74 Simulation Run = 78 Weights = [0.19 0.008 0.158 0.127 0.076 0.027 0.086 0.078 0.198 0.052], Final Value = $3484667.45, Sharpe Ratio = 0.74 Simulation Run = 79 Weights = [0.126 0.106 0.157 0.027 0.113 0.02 0.046 0.113 0.184 0.108], Final Value = $3395454.39, Sharpe Ratio = 0.72 Simulation Run = 80 Weights = [0.061 0.154 0.078 0.057 0.042 0.017 0.166 0.177 0.174 0.074], Final Value = $3041487.49, Sharpe Ratio = 0.65 Simulation Run = 81 Weights = [0.155 0.093 0.205 0.083 0.113 0.102 0.09 0.081 0.061 0.018], Final Value = $3650040.50, Sharpe Ratio = 0.75 Simulation Run = 82 Weights = [0.137 0.119 0.004 0.112 0.065 0.048 0.178 0.152 0.074 0.111], Final Value = $2975188.81, Sharpe Ratio = 0.66 Simulation Run = 83 Weights = [0.099 0.012 0.063 0.147 0.103 0.035 0.166 0.165 0.183 0.026], Final Value = $3040072.35, Sharpe Ratio = 0.66 Simulation Run = 84 Weights = [0.056 0.049 0.013 0.116 0.037 0.082 0.145 0.19 0.204 0.107], Final Value = $2742516.52, Sharpe Ratio = 0.63 Simulation Run = 85 Weights = [0.047 0.039 0.175 0.164 0.071 0.076 0.181 0.072 0.121 0.054], Final Value = $3338592.48, Sharpe Ratio = 0.72 Simulation Run = 86 Weights = [0.161 0.087 0.154 0.026 0.161 0.149 0.049 0.125 0.029 0.06 ], Final Value = $3470731.70, Sharpe Ratio = 0.71 Simulation Run = 87 Weights = [0.116 0.062 0.166 0.166 0.139 0.013 0.062 0.095 0.085 0.096], Final Value = $3466045.57, Sharpe Ratio = 0.74 Simulation Run = 88 Weights = [0.111 0.065 0.157 0.053 0.001 0.178 0.125 0.094 0.078 0.139], Final Value = $3287546.71, Sharpe Ratio = 0.73 Simulation Run = 89 Weights = [0.05 0.074 0.137 0.174 0.064 0.049 0.154 0.192 0.046 0.06 ], Final Value = $3209044.58, Sharpe Ratio = 0.68 Simulation Run = 90 Weights = [0.044 0.184 0.158 0.032 0.134 0.089 0.102 0.154 0.097 0.005], Final Value = $3338863.92, Sharpe Ratio = 0.68 Simulation Run = 91 Weights = [0.027 0.163 0.174 0.179 0.06 0.068 0.002 0.028 0.172 0.127], Final Value = $3349551.79, Sharpe Ratio = 0.73 Simulation Run = 92 Weights = [0.072 0.16 0.013 0.179 0.045 0.025 0.059 0.167 0.097 0.181], Final Value = $2882416.81, Sharpe Ratio = 0.66 Simulation Run = 93 Weights = [0.124 0.071 0.094 0.01 0.193 0.055 0.25 0.064 0.11 0.029], Final Value = $3301209.30, Sharpe Ratio = 0.67 Simulation Run = 94 Weights = [0.116 0.032 0.148 0.13 0.148 0.079 0.094 0.044 0.089 0.119], Final Value = $3397080.77, Sharpe Ratio = 0.74 Simulation Run = 95 Weights = [0.094 0.066 0.178 0.081 0.128 0.119 0.015 0.155 0.02 0.144], Final Value = $3377796.29, Sharpe Ratio = 0.72 Simulation Run = 96 Weights = [0.185 0.11 0.014 0.023 0.155 0.129 0.116 0.097 0.097 0.075], Final Value = $3110380.99, Sharpe Ratio = 0.67 Simulation Run = 97 Weights = [0.078 0.104 0.095 0.058 0.111 0.072 0.19 0.026 0.125 0.141], Final Value = $3187272.28, Sharpe Ratio = 0.70 Simulation Run = 98 Weights = [0.021 0.042 0.107 0.119 0.179 0.096 0.084 0.132 0.087 0.133], Final Value = $3077456.43, Sharpe Ratio = 0.68 Simulation Run = 99 Weights = [0.004 0.187 0.127 0.038 0.171 0.088 0.179 0.023 0.165 0.018], Final Value = $3257805.17, Sharpe Ratio = 0.67
In [253]:
sharpe_ratio_runs
Out[253]:
array([0.68705802, 0.67759902, 0.73184411, 0.64114971, 0.69411339,
0.66268488, 0.74499705, 0.63512504, 0.68784824, 0.68648812,
0.71600236, 0.70522515, 0.67939041, 0.69768789, 0.63436387,
0.66772974, 0.61997874, 0.69532053, 0.69536666, 0.68802506,
0.63862295, 0.66443313, 0.68696603, 0.6803914 , 0.70075526,
0.73961134, 0.73676401, 0.70893938, 0.70751088, 0.68236447,
0.66696501, 0.68943513, 0.67470913, 0.66913011, 0.71419393,
0.67834893, 0.74609042, 0.61675153, 0.60959401, 0.63134499,
0.75423752, 0.69500272, 0.72241294, 0.73830318, 0.70545709,
0.63085639, 0.70271176, 0.69797388, 0.71044707, 0.65191536,
0.74952076, 0.68885269, 0.66642693, 0.71593543, 0.70151882,
0.75783011, 0.74104933, 0.66700981, 0.69806778, 0.66006645,
0.72601808, 0.72221369, 0.70853416, 0.67118289, 0.71337311,
0.65898187, 0.68062563, 0.65568793, 0.66054561, 0.66640597,
0.70679692, 0.67901765, 0.62221805, 0.6639664 , 0.67195612,
0.66521769, 0.67793132, 0.73847718, 0.7440054 , 0.72072083,
0.65491718, 0.74541003, 0.65505378, 0.65854169, 0.62652396,
0.71529281, 0.71114577, 0.73536064, 0.73005152, 0.67710343,
0.678965 , 0.72989698, 0.65918224, 0.67342607, 0.74172878,
0.71651075, 0.66879721, 0.69990279, 0.67924659, 0.67064814])
In [267]:
sharpe_ratio_runs.max()
Out[267]:
0.7578301149343443
In [269]:
sharpe_ratio_runs.argmax()
Out[269]:
55
In [271]:
weight_runs
Out[271]:
array([[8.97154292e-02, 6.56643859e-02, 1.13341367e-01, 5.53594064e-03,
2.50411173e-03, 1.83683020e-01, 1.22597038e-01, 1.40643428e-01,
1.73792194e-01, 1.02523086e-01],
[1.64792182e-01, 4.97423046e-02, 4.78990063e-02, 4.69743786e-02,
1.77672222e-01, 1.05922283e-01, 5.96065071e-02, 1.11759376e-01,
1.20455743e-01, 1.15175998e-01],
[1.65832315e-01, 1.88857680e-01, 1.32483746e-01, 2.77317352e-02,
4.82868246e-02, 4.77273848e-02, 1.30494787e-01, 6.13431662e-03,
1.35813516e-01, 1.16637695e-01],
[3.89373116e-02, 1.79992397e-01, 3.86885483e-02, 4.13864830e-03,
5.62093233e-02, 1.50396100e-01, 1.91123058e-01, 1.28173002e-01,
7.69977135e-02, 1.35343898e-01],
[2.56105011e-02, 1.67835074e-01, 1.30286745e-01, 7.40441607e-02,
1.27895145e-01, 1.34587197e-01, 5.18205039e-02, 1.24740952e-01,
5.24391625e-02, 1.10740559e-01],
[1.35950196e-01, 1.45619243e-01, 1.46880914e-02, 1.57692171e-01,
1.62288113e-01, 1.57569463e-02, 1.27856153e-01, 1.28709043e-01,
3.73194969e-03, 1.07708094e-01],
[1.24511681e-01, 8.54269523e-02, 1.88990874e-01, 3.95649751e-02,
7.47345136e-02, 9.59785550e-02, 5.34481421e-02, 9.57809171e-02,
9.34221670e-02, 1.48141222e-01],
[1.68346425e-02, 5.09640583e-02, 8.61685380e-02, 1.61809995e-03,
1.74466040e-02, 9.98864232e-02, 1.73223367e-01, 1.85317972e-01,
1.84584314e-01, 1.83955981e-01],
[3.11798343e-02, 1.54547949e-01, 1.81099456e-01, 6.72485903e-03,
1.40629089e-01, 2.41482367e-02, 6.73406570e-02, 1.58997246e-01,
9.20069532e-02, 1.43325721e-01],
[1.04210116e-01, 2.59461943e-02, 1.11630765e-01, 1.08889704e-01,
9.68674672e-02, 1.53411751e-01, 1.13225111e-01, 1.68318027e-01,
2.25913499e-02, 9.49095155e-02],
[2.05118400e-01, 2.38050471e-02, 4.56793203e-02, 2.20092555e-01,
1.06710673e-06, 1.44312509e-01, 2.70544031e-02, 6.12608896e-02,
4.97190563e-02, 2.22956753e-01],
[1.80211385e-01, 7.86036534e-02, 1.55516669e-02, 1.70172433e-01,
8.09346638e-02, 1.10399511e-01, 7.55723419e-02, 4.65657447e-02,
1.76468423e-01, 6.55201772e-02],
[7.35301114e-02, 2.14456201e-01, 1.30594658e-02, 1.49348392e-01,
1.73888461e-01, 1.59801524e-01, 1.73358038e-02, 6.86291753e-02,
1.31289614e-02, 1.16821905e-01],
[1.96096361e-01, 1.48096685e-01, 7.67353178e-02, 7.79899731e-04,
1.00098756e-01, 1.29382551e-01, 1.90324537e-01, 4.85880485e-02,
5.97977071e-02, 5.01001371e-02],
[1.49409966e-02, 1.18483276e-01, 2.73095701e-02, 1.10594641e-01,
8.33294048e-03, 8.11222630e-02, 2.30118193e-01, 1.07499320e-01,
1.21686556e-01, 1.79912245e-01],
[1.46476384e-02, 1.05718330e-02, 1.23331391e-01, 3.89984510e-02,
4.28183761e-02, 2.14259549e-01, 1.18195408e-01, 8.28163958e-02,
2.72465419e-01, 8.18955380e-02],
[6.59509791e-03, 1.34630301e-01, 2.52447419e-03, 1.84841431e-01,
8.67089033e-02, 1.27288958e-01, 1.17599478e-01, 1.97834386e-01,
3.21837531e-02, 1.09793217e-01],
[1.25605464e-01, 9.22124954e-02, 1.40635093e-02, 1.30428312e-01,
1.67492362e-01, 2.27209954e-01, 6.64561251e-03, 3.52385742e-03,
1.83175725e-01, 4.96427078e-02],
[7.62920846e-02, 9.52031762e-02, 1.10166212e-01, 7.01500730e-02,
1.43409767e-01, 9.47632600e-02, 1.12098720e-01, 1.18025042e-01,
7.88674518e-02, 1.01024213e-01],
[1.15297960e-01, 1.88283175e-01, 1.29586175e-01, 1.61706739e-01,
2.42924596e-02, 3.29243360e-03, 1.99634418e-01, 1.32388916e-01,
4.20560220e-02, 3.46170176e-03],
[4.54417242e-02, 5.52470261e-02, 9.78857145e-03, 1.97494839e-01,
1.74529685e-02, 7.04534612e-02, 1.72923170e-01, 1.16069278e-01,
2.34869662e-01, 8.02592986e-02],
[1.02210203e-01, 1.18534253e-01, 1.18720086e-02, 8.16873963e-02,
1.58681023e-01, 1.41640484e-01, 7.33981480e-02, 1.12048582e-01,
1.47291516e-01, 5.26363861e-02],
[3.00150962e-02, 8.16953275e-02, 7.20418504e-02, 1.07081097e-01,
1.59046780e-01, 1.60600006e-01, 6.87203310e-02, 7.72580903e-02,
6.10374960e-02, 1.82503926e-01],
[2.76813366e-03, 9.77620174e-02, 1.18242290e-01, 1.49766952e-01,
8.91865383e-02, 1.27946660e-01, 2.86861159e-02, 1.63178622e-01,
1.58552903e-01, 6.39097671e-02],
[1.45607619e-01, 3.17406186e-02, 1.51071710e-01, 4.96408728e-02,
1.55857135e-01, 1.81488627e-02, 3.59166945e-02, 1.52750435e-01,
1.70101462e-01, 8.91645904e-02],
[1.25865138e-01, 1.34024334e-01, 1.26781905e-01, 8.30785172e-02,
1.06281098e-01, 1.07473090e-01, 1.10509117e-01, 3.15199811e-03,
5.61840401e-02, 1.46650762e-01],
[1.19151758e-01, 1.31325605e-02, 1.73306333e-01, 7.36920287e-02,
1.04019462e-01, 6.18528810e-02, 1.28410122e-01, 7.61303613e-02,
1.10013100e-01, 1.40291394e-01],
[1.90165483e-02, 5.00343822e-02, 1.43012446e-01, 1.49706846e-01,
1.52664750e-01, 1.36395424e-01, 1.25314588e-01, 5.50454532e-02,
5.25269341e-02, 1.16282630e-01],
[1.76668552e-01, 1.73671131e-01, 2.95253689e-02, 1.58833852e-01,
5.33093183e-02, 1.97837472e-01, 4.78960559e-02, 8.23570661e-02,
5.35169768e-02, 2.63842061e-02],
[9.92556006e-02, 1.10469386e-01, 8.47217384e-02, 1.36033615e-01,
1.59579680e-01, 7.33128450e-02, 6.22991234e-03, 1.67518653e-01,
7.91030071e-02, 8.37755629e-02],
[3.05283777e-02, 1.77400849e-01, 9.57203497e-02, 9.47560802e-02,
1.18520822e-01, 1.40481382e-01, 1.31227826e-01, 1.46248895e-01,
4.25125185e-02, 2.26029004e-02],
[6.32745284e-02, 1.69835224e-01, 3.74905253e-02, 7.08473289e-02,
1.51813021e-01, 1.55261174e-01, 6.82469933e-02, 1.43000488e-02,
1.57781446e-01, 1.11149711e-01],
[9.82283744e-02, 1.08375576e-01, 4.33948984e-02, 1.12395552e-01,
1.34518548e-01, 6.75218103e-02, 9.63365835e-02, 1.33724218e-01,
1.22349003e-01, 8.31554377e-02],
[1.32122248e-01, 3.30712090e-02, 7.06602565e-02, 2.39900559e-02,
1.21486005e-01, 8.89577818e-02, 1.30834248e-01, 1.50946152e-01,
1.03279794e-01, 1.44652251e-01],
[3.86310121e-02, 2.30910044e-01, 2.07026959e-01, 2.65867312e-02,
4.99007902e-02, 2.07511765e-01, 6.49287972e-02, 1.02473939e-02,
5.08210549e-02, 1.13435453e-01],
[4.89786823e-02, 1.82201959e-01, 8.05243025e-03, 1.22268665e-01,
1.52446114e-01, 1.64053826e-01, 4.15161979e-02, 2.81355622e-02,
1.05281241e-01, 1.47065322e-01],
[8.95836940e-02, 3.38716833e-02, 2.12196660e-01, 7.11594633e-02,
1.31678256e-01, 6.87185047e-02, 1.50819692e-01, 1.16407114e-02,
2.40795147e-02, 2.06251820e-01],
[8.01959256e-02, 1.75690304e-01, 2.83603571e-02, 1.13626514e-02,
1.89362885e-01, 1.88027394e-02, 1.85016369e-01, 1.89777671e-01,
7.98171203e-02, 4.16139779e-02],
[7.06762319e-03, 2.27039276e-01, 8.38398988e-03, 1.24056302e-02,
3.44058368e-02, 1.20307096e-01, 1.42018545e-01, 1.90069164e-01,
3.10902112e-02, 2.27212628e-01],
[4.45280360e-02, 3.77084704e-01, 1.25755464e-02, 3.11990985e-02,
6.99402169e-02, 1.09477701e-01, 3.06228421e-02, 1.44151038e-01,
1.21431165e-01, 5.89896524e-02],
[1.64932998e-01, 2.43314874e-03, 1.82183849e-01, 1.73521825e-02,
1.91586773e-01, 3.83303286e-02, 5.61278955e-03, 7.35116648e-04,
1.72771414e-01, 2.24061399e-01],
[1.41871940e-01, 4.49628911e-02, 6.10592645e-02, 3.83066002e-02,
1.11375480e-01, 1.87813631e-01, 1.38259468e-03, 9.41340870e-02,
1.42474907e-01, 1.76618605e-01],
[1.09011388e-01, 9.74917555e-02, 1.00167785e-01, 1.23850941e-01,
2.04298322e-01, 1.96726776e-02, 1.12490134e-01, 1.36676408e-03,
1.17936051e-01, 1.13714182e-01],
[1.88517874e-01, 9.93499055e-02, 1.23907018e-01, 1.40377436e-01,
3.25091720e-02, 1.06690541e-01, 3.36942899e-02, 1.13420373e-01,
5.69872506e-02, 1.04546139e-01],
[8.55123088e-02, 4.09713856e-02, 9.32482129e-02, 9.28775079e-02,
1.40997115e-01, 9.72980779e-02, 1.44346945e-01, 5.46173251e-02,
1.34707074e-01, 1.15424048e-01],
[1.45116091e-03, 2.44726110e-01, 1.21500886e-02, 1.44250520e-01,
1.08160095e-01, 8.40357293e-02, 1.77158740e-01, 1.11846803e-01,
7.36566013e-02, 4.25641530e-02],
[7.31638310e-02, 3.52224634e-02, 1.42413211e-01, 1.15213802e-01,
5.17471398e-02, 1.00533003e-01, 1.67741989e-01, 1.26020612e-01,
1.26077882e-02, 1.75336161e-01],
[7.48494629e-02, 8.85124784e-02, 1.10291036e-01, 1.42758716e-01,
1.15619463e-01, 1.18785477e-01, 1.06725224e-01, 1.25965707e-01,
1.08007272e-01, 8.48516307e-03],
[1.17363689e-01, 1.43464271e-01, 8.60362643e-02, 1.53565893e-01,
1.54939497e-01, 1.50650289e-01, 4.16361817e-03, 9.91460893e-02,
3.52539785e-03, 8.71449916e-02],
[8.30764033e-02, 7.93770529e-02, 2.07654801e-02, 6.24954630e-02,
3.10702759e-02, 1.78593045e-01, 5.91782211e-02, 1.33231430e-01,
2.56862977e-01, 9.53496510e-02],
[1.28931211e-01, 5.39961135e-02, 1.44156332e-01, 1.83149201e-01,
1.44993463e-01, 1.03945369e-01, 9.35441290e-02, 5.89751582e-03,
1.68065528e-02, 1.24580113e-01],
[1.42813219e-01, 5.45053307e-02, 1.44275876e-01, 1.29124179e-02,
3.43832168e-03, 1.89091719e-01, 2.29495225e-02, 2.02812961e-01,
1.90345180e-01, 3.68554529e-02],
[1.12355919e-01, 1.95591557e-01, 2.51521978e-02, 1.64702539e-01,
7.96656653e-02, 1.69170731e-02, 9.67213302e-02, 1.59501968e-01,
2.92864133e-02, 1.20105337e-01],
[4.43976134e-02, 9.87057396e-02, 2.87545162e-01, 9.96130385e-02,
4.24072408e-02, 1.01669278e-01, 9.58532113e-03, 2.15529042e-01,
3.55793407e-02, 6.49682248e-02],
[5.89866045e-02, 1.49933460e-01, 8.06227389e-02, 1.56890162e-01,
1.19314353e-01, 1.40362020e-01, 1.12396658e-01, 3.82139963e-02,
1.26791800e-01, 1.64882075e-02],
[1.50453233e-01, 1.28920488e-01, 1.79020637e-01, 1.19658285e-01,
9.45116146e-02, 2.86297113e-02, 5.78075428e-02, 4.49907383e-02,
6.06618587e-02, 1.35345891e-01],
[5.94378823e-02, 1.81157500e-01, 1.95163205e-01, 1.32265312e-01,
9.19927956e-02, 6.79565816e-02, 1.67596631e-02, 2.85781940e-02,
1.71989632e-01, 5.46992354e-02],
[4.84129376e-02, 1.46685460e-01, 8.98322759e-02, 5.56418852e-02,
1.43296370e-01, 1.18807776e-01, 1.10530705e-01, 1.47686814e-01,
1.29036712e-01, 1.00690635e-02],
[1.38569629e-01, 8.14414575e-02, 1.19744323e-01, 4.40946552e-02,
9.82525084e-02, 5.49431428e-02, 1.63196380e-01, 1.26206570e-01,
7.23061679e-02, 1.01245168e-01],
[3.23853224e-02, 9.11556670e-02, 5.67364993e-02, 1.04382617e-01,
7.97867185e-02, 7.82627036e-02, 5.68732255e-02, 1.65521014e-01,
1.69258698e-01, 1.65637535e-01],
[2.29362952e-02, 3.89237100e-02, 2.09227065e-01, 1.99557022e-01,
1.77344247e-01, 2.25458618e-02, 1.49031508e-01, 2.67029460e-04,
4.65974381e-02, 1.33569824e-01],
[1.07790524e-01, 5.99454935e-02, 1.49309068e-01, 1.42507147e-01,
5.85141572e-02, 1.62498362e-01, 1.35005720e-02, 1.54417553e-01,
7.75456505e-02, 7.39714727e-02],
[1.03324363e-01, 1.47371641e-01, 9.86625790e-02, 2.80542900e-02,
1.39755652e-01, 6.69071379e-02, 1.22194469e-01, 2.83362444e-02,
1.72326601e-01, 9.30670229e-02],
[6.96631409e-02, 8.14329163e-02, 5.08364153e-02, 6.33896043e-02,
6.50736318e-02, 7.98776817e-02, 2.07766997e-01, 1.58182550e-02,
2.29116590e-01, 1.37024768e-01],
[1.38535049e-01, 1.23484473e-01, 3.94645089e-02, 1.63007992e-01,
1.63851781e-01, 4.95498766e-02, 7.77551232e-02, 1.60637400e-02,
7.13292148e-02, 1.56958243e-01],
[7.18142287e-02, 3.63710183e-02, 9.89520791e-03, 1.48224003e-01,
1.81239780e-01, 1.49184417e-01, 9.54662501e-02, 9.06999245e-02,
1.28011546e-01, 8.90936247e-02],
[6.59850612e-02, 2.64194682e-02, 9.08860429e-02, 1.60396987e-01,
3.67165165e-03, 1.21170942e-02, 2.36162223e-01, 1.41943349e-02,
1.79007378e-01, 2.11159759e-01],
[1.98409077e-01, 1.10711816e-01, 7.20225447e-02, 7.79943005e-02,
1.98266941e-01, 5.65588950e-03, 1.18448313e-01, 1.72240950e-01,
4.42220655e-03, 4.18279603e-02],
[7.32114383e-03, 2.34521447e-02, 5.54419592e-02, 1.99758115e-01,
1.89735470e-01, 7.80273495e-02, 1.75871319e-02, 1.00631728e-01,
1.50370687e-01, 1.77674271e-01],
[1.74290184e-01, 1.94197404e-02, 3.26995443e-02, 7.33730976e-02,
3.16259750e-02, 1.09834761e-01, 1.45633143e-01, 1.54901405e-01,
1.20038578e-01, 1.38183572e-01],
[9.52205410e-02, 1.62837464e-01, 1.18731922e-01, 2.03725947e-02,
4.37025141e-02, 1.69151687e-01, 2.07871210e-02, 1.32899864e-01,
1.08147336e-01, 1.28148957e-01],
[9.77293941e-02, 2.04366620e-01, 8.64689184e-02, 2.06757408e-02,
1.80031312e-02, 1.29938431e-01, 9.41319875e-02, 1.60175653e-01,
5.97524991e-02, 1.28757625e-01],
[7.91195240e-02, 1.55289521e-02, 4.01935314e-04, 1.86405912e-01,
1.07939955e-01, 1.67986587e-01, 1.16492088e-01, 1.96073030e-01,
8.77601608e-03, 1.21276001e-01],
[9.63376324e-02, 1.32626417e-01, 2.58444001e-02, 7.58277772e-02,
1.03776737e-01, 9.03199030e-02, 1.44004057e-01, 1.32062537e-01,
7.65643440e-02, 1.22636195e-01],
[1.72360661e-01, 2.67034400e-02, 1.65502307e-03, 1.53908406e-01,
2.36836003e-01, 1.07837160e-01, 6.14706388e-02, 5.48019477e-02,
9.91321022e-02, 8.52946181e-02],
[8.32069919e-02, 1.02184704e-01, 7.30903542e-03, 1.46403641e-01,
9.84741502e-02, 8.78717454e-02, 1.45143704e-01, 1.05082395e-01,
1.16805528e-01, 1.07518106e-01],
[1.17121280e-02, 7.29352916e-02, 1.14378699e-01, 1.12653119e-01,
1.19650319e-01, 1.41379577e-01, 8.26278471e-02, 1.54341108e-01,
1.08897145e-01, 8.14247675e-02],
[1.53688750e-01, 3.50185009e-02, 1.28597601e-01, 1.37159945e-01,
4.67727913e-02, 1.79456398e-01, 1.27655904e-01, 6.22494465e-02,
9.40687276e-02, 3.53319359e-02],
[1.89837337e-01, 7.74658878e-03, 1.58436020e-01, 1.27311345e-01,
7.56601008e-02, 2.68051989e-02, 8.62713575e-02, 7.79151065e-02,
1.97535822e-01, 5.24811231e-02],
[1.26237621e-01, 1.06311263e-01, 1.57240104e-01, 2.67241232e-02,
1.12912267e-01, 1.95671274e-02, 4.61836321e-02, 1.12642503e-01,
1.84052815e-01, 1.08128543e-01],
[6.11227307e-02, 1.54163016e-01, 7.79137534e-02, 5.68311030e-02,
4.21566646e-02, 1.68135227e-02, 1.65848416e-01, 1.77047731e-01,
1.73890452e-01, 7.42126112e-02],
[1.54511583e-01, 9.33947681e-02, 2.05086699e-01, 8.28162649e-02,
1.12615042e-01, 1.01743030e-01, 8.97496089e-02, 8.14908359e-02,
6.05787498e-02, 1.80134178e-02],
[1.36988384e-01, 1.19251521e-01, 3.96805887e-03, 1.11797813e-01,
6.53209976e-02, 4.81614749e-02, 1.77571260e-01, 1.52087778e-01,
7.36495765e-02, 1.11203137e-01],
[9.90479106e-02, 1.18957549e-02, 6.31832082e-02, 1.46601633e-01,
1.03406313e-01, 3.53851309e-02, 1.66331741e-01, 1.65214535e-01,
1.83092443e-01, 2.58413296e-02],
[5.61519470e-02, 4.94701498e-02, 1.30564997e-02, 1.15887141e-01,
3.73129737e-02, 8.18079722e-02, 1.45314785e-01, 1.90493793e-01,
2.03818553e-01, 1.06686186e-01],
[4.74446403e-02, 3.87797150e-02, 1.74857877e-01, 1.63892314e-01,
7.10418073e-02, 7.59060948e-02, 1.80718270e-01, 7.21234687e-02,
1.20769580e-01, 5.44662335e-02],
[1.60720047e-01, 8.73760222e-02, 1.53733821e-01, 2.62758960e-02,
1.60979159e-01, 1.49389126e-01, 4.87774990e-02, 1.24585126e-01,
2.85514279e-02, 5.96118759e-02],
[1.16126387e-01, 6.23731313e-02, 1.65604625e-01, 1.66289841e-01,
1.38951401e-01, 1.27506164e-02, 6.18028000e-02, 9.52353762e-02,
8.52058186e-02, 9.56600031e-02],
[1.11104702e-01, 6.45885107e-02, 1.57026133e-01, 5.34373774e-02,
8.57650333e-04, 1.77889140e-01, 1.24775949e-01, 9.36072856e-02,
7.79300946e-02, 1.38783158e-01],
[5.01062999e-02, 7.37888206e-02, 1.37158152e-01, 1.74366839e-01,
6.39592555e-02, 4.90203990e-02, 1.53613770e-01, 1.91567450e-01,
4.63733015e-02, 6.00457131e-02],
[4.39864588e-02, 1.84308564e-01, 1.58358379e-01, 3.15597633e-02,
1.34295920e-01, 8.93454878e-02, 1.02004189e-01, 1.54476474e-01,
9.69884075e-02, 4.67635592e-03],
[2.71658257e-02, 1.63027378e-01, 1.74219957e-01, 1.78642604e-01,
6.03194796e-02, 6.83567161e-02, 1.60627284e-03, 2.82873232e-02,
1.71841124e-01, 1.26533321e-01],
[7.24892974e-02, 1.60276668e-01, 1.28983501e-02, 1.79400350e-01,
4.48013515e-02, 2.51840702e-02, 5.92064847e-02, 1.67191871e-01,
9.71928846e-02, 1.81358673e-01],
[1.24419777e-01, 7.13213622e-02, 9.39018986e-02, 1.02293740e-02,
1.92614951e-01, 5.46056147e-02, 2.50016645e-01, 6.36776873e-02,
1.09885326e-01, 2.93273644e-02],
[1.15719802e-01, 3.21864509e-02, 1.48482815e-01, 1.30356016e-01,
1.48205010e-01, 7.86031052e-02, 9.35325266e-02, 4.40450300e-02,
8.94266551e-02, 1.19442589e-01],
[9.44801343e-02, 6.56803390e-02, 1.77588708e-01, 8.14198055e-02,
1.27641193e-01, 1.18730614e-01, 1.52812704e-02, 1.54989462e-01,
2.02686783e-02, 1.43919795e-01],
[1.85131895e-01, 1.10221868e-01, 1.36505483e-02, 2.27803676e-02,
1.54779446e-01, 1.29066143e-01, 1.15655878e-01, 9.70988919e-02,
9.65772506e-02, 7.50377125e-02],
[7.80738450e-02, 1.04316837e-01, 9.46285897e-02, 5.84407003e-02,
1.10592785e-01, 7.23295841e-02, 1.89739523e-01, 2.60216741e-02,
1.24956919e-01, 1.40899543e-01],
[2.09546961e-02, 4.18686535e-02, 1.07496957e-01, 1.18741782e-01,
1.79308467e-01, 9.58204392e-02, 8.39166036e-02, 1.32178764e-01,
8.67530833e-02, 1.32960554e-01],
[3.90728544e-03, 1.86757153e-01, 1.27106946e-01, 3.75768391e-02,
1.70672639e-01, 8.82855788e-02, 1.79385173e-01, 2.30063654e-02,
1.64932050e-01, 1.83699698e-02]])
In [273]:
weight_runs[sharpe_ratio_runs.argmax(),:]
Out[273]:
array([0.15045323, 0.12892049, 0.17902064, 0.11965829, 0.09451161,
0.02862971, 0.05780754, 0.04499074, 0.06066186, 0.13534589])
In [275]:
optimal_portfolio_return, optimal_volatility, optimal_sharpe_ratio, highest_final_value, optimal_return_on_investment = simulation_engine(weight_runs[sharpe_ratio_runs.argmax(),:], initial_investment)
In [277]:
print('Best Portfolio Metrics Based on {} Monte Carlo Simulation Runs:'.format(sim_runs))
print(' - Portfolio Expected Annual Return = {:.02f}%'.format(optimal_portfolio_return * 100))
print(' - Portfolio Standard Deviation (Volatility) = {:.02f}%'.format(optimal_volatility * 100))
print(' - Sharpe Ratio = {:.02f}'.format(optimal_sharpe_ratio))
print(' - Final Value = ${:.02f}'.format(highest_final_value))
print(' - Return on Investment = {:.02f}%'.format(optimal_return_on_investment))
Best Portfolio Metrics Based on 100 Monte Carlo Simulation Runs: - Portfolio Expected Annual Return = 17.57% - Portfolio Standard Deviation (Volatility) = 18.57% - Sharpe Ratio = 0.76 - Final Value = $3588434.01 - Return on Investment = 258.84%
In [304]:
sim_out_df = pd.DataFrame({'Volatility' :volatility_runs.tolist(),'Portfolio_return' : expected_portfolio_return_runs.tolist(),
'Sharpe_ratio' :sharpe_ratio_runs.tolist()})
sim_out_df
Out[304]:
| Volatility | Portfolio_return | Sharpe_ratio | |
|---|---|---|---|
| 0 | 0.176224 | 0.156076 | 0.687058 |
| 1 | 0.186944 | 0.161673 | 0.677599 |
| 2 | 0.186535 | 0.171515 | 0.731844 |
| 3 | 0.183671 | 0.152761 | 0.641150 |
| 4 | 0.183495 | 0.162366 | 0.694113 |
| ... | ... | ... | ... |
| 95 | 0.186645 | 0.168733 | 0.716511 |
| 96 | 0.190815 | 0.162616 | 0.668797 |
| 97 | 0.178514 | 0.159942 | 0.699903 |
| 98 | 0.180363 | 0.157511 | 0.679247 |
| 99 | 0.191640 | 0.163523 | 0.670648 |
100 rows × 3 columns
In [308]:
import plotly.graph_objects as go
fig = px.scatter(sim_out_df, x = 'Volatility', y = 'Portfolio_return', color = 'Sharpe_ratio', size = 'Sharpe_ratio', hover_data = ['Sharpe_ratio'] )
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
In [312]:
fig = px.scatter(sim_out_df, x = 'Volatility', y = 'Portfolio_return', color = 'Sharpe_ratio', size = 'Sharpe_ratio', hover_data = ['Sharpe_ratio'] )
fig.add_trace(go.Scatter(x = [optimal_volatility], y = [optimal_portfolio_return], mode = 'markers', name = 'Optimal Point', marker = dict(size=[40], color = 'green')))
fig.update_layout(coloraxis_colorbar = dict(y = 0.7, dtick = 5))
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
In [ ]: